package jy.service.impl;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import jy.dao.AccountDaoI;
import jy.dao.DataDaoI;
import jy.dao.DemandDaoI;
import jy.dao.FixedDaoI;
import jy.dao.TraderecordDaoI;
import jy.dao.UserDaoI;
import jy.model.Taccount;
import jy.model.Tdemand;
import jy.model.Tfixed;
import jy.model.Trole;
import jy.model.Ttraderecord;
import jy.model.Tuser;
import jy.pageModel.Account;
import jy.pageModel.DataGrid;
import jy.pageModel.Fixed;
import jy.pageModel.PageHelper;
import jy.pageModel.Traderecord;
import jy.pageModel.User;
import jy.service.AccountServiceI;
import jy.util.ComputeUtil;
import jy.util.DateUtil;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AccountServiceImpl implements AccountServiceI {

	@Autowired
	private UserDaoI userDao;

	@Autowired
	private AccountDaoI accountDao;

	@Autowired
	private FixedDaoI fixedDao;

	@Autowired
	private DemandDaoI demandDao;

	@Autowired
	private DataDaoI dataDao;

	@Autowired
	private TraderecordDaoI traderecordDao;

	@Override
	public DataGrid dataGrid(Account account, PageHelper ph) {
		DataGrid dg = new DataGrid();
		List<Account> acl = new ArrayList<Account>();
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("uid", account.getUid());
		String hql = " from Taccount t where uid = :uid";
		List<Taccount> l = accountDao.find(hql + orderHql(ph), params,
				ph.getPage(), ph.getRows());
		if (l != null && l.size() > 0) {
			for (Taccount t : l) {
				Account ac = new Account();
				BeanUtils.copyProperties(t, ac);
				switch (t.getType()) {
				case 1:
					ac.setTypeStr("活期");
					break;
				case 2:
					ac.setTypeStr("定期");
					break;
				case 3:
					ac.setTypeStr("定活");
					break;
				}
				switch (t.getCurrency()) {
				case 1:
					ac.setCurrencyStr("人民币");
					break;
				case 2:
					ac.setCurrencyStr("美元");
					break;
				case 3:
					ac.setCurrencyStr("港币");
					break;
				case 4:
					ac.setCurrencyStr("日元");
					break;
				case 5:
					ac.setCurrencyStr("欧元");
					break;
				}
				acl.add(ac);
			}
		}
		dg.setRows(acl);
		dg.setTotal(accountDao.count("select count(*) " + hql, params));
		return dg;
	}

	private String orderHql(PageHelper ph) {
		String orderString = "";
		if (ph.getSort() != null && ph.getOrder() != null) {
			orderString = " order by t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}

	@Override
	synchronized public Integer add(Account account) {
		account.setId(UUID.randomUUID().toString());
		Taccount ac = new Taccount();
		BeanUtils.copyProperties(account, ac);
		ac.setStime(new Date());
		ac.setTuser(userDao.get(Tuser.class, account.getUid()));
		Integer nextId = 0;
		try {
			nextId = getNextId(account.getType(), account.getCurrency(),
					account.getUid());
		} catch (Exception e) {
			e.printStackTrace();
		}
		ac.setName(nextId.toString());// 编号
		System.out.println(ac.toString());
		accountDao.save(ac);

		switch (account.getType()) {
		case 1:
			Tdemand d = new Tdemand();
			d.setId(UUID.randomUUID().toString());
			d.setTaccount(ac);
			d.setAmount(0);
			demandDao.save(d);
			break;
		case 2:
			break;
		case 3:
			break;
		}

		return nextId;

	}

	synchronized public Integer getNextId(Integer type, Integer currency,
			String uid) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("type", type);
		params.put("currency", currency);
		params.put("uid", uid);
		Integer result = 0;
		if (accountDao
				.count("select count(*) from Taccount s where s.type=:type and s.currency = :currency and s.tuser.id=:uid ",
						params) == 0) {
			result = (currency * 10 + type) * 1000;
		} else {
			result = Integer
					.parseInt(accountDao
							.get("from Taccount  t where  t.name =(select max(name) from Taccount s where s.type=:type and s.currency = :currency and s.tuser.id=:uid )",
									params).getName()) + 1;
		}
		return result;
	}

	@Override
	public User get(String id) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		Tuser t = userDao
				.get("select distinct t from Tuser t left join fetch t.troles role where t.id = :id",
						params);
		User u = new User();
		BeanUtils.copyProperties(t, u);
		System.out.println(u.getName() + u.getIdn());
		if (t.getTroles() != null && !t.getTroles().isEmpty()) {
			String roleIds = "";
			String roleNames = "";
			boolean b = false;
			for (Trole role : t.getTroles()) {
				if (b) {
					roleIds += ",";
					roleNames += ",";
				} else {
					b = true;
				}
				roleIds += role.getId();
				roleNames += role.getName();
			}
			u.setRoleIds(roleIds);
			u.setRoleNames(roleNames);
		}
		return u;
	}

	@Override
	public void delete(String id) {
		accountDao.delete(accountDao.get(Taccount.class, id));
	}

	@Override
	public DataGrid recdataGrid(Account account, PageHelper ph) {
		DataGrid dg = new DataGrid();
		List<Traderecord> acl = new ArrayList<Traderecord>();
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("acid", account.getId());
		String hql = " from Ttraderecord t where t.taccount.id = :acid";
		List<Ttraderecord> l = traderecordDao.find(hql + orderHql(ph), params,
				ph.getPage(), ph.getRows());
		if (l != null && l.size() > 0) {
			for (Ttraderecord t : l) {
				Traderecord tr = new Traderecord();
				BeanUtils.copyProperties(t, tr);
				acl.add(tr);
			}
		}
		dg.setRows(acl);
		dg.setTotal(traderecordDao.count("select count(*) " + hql, params));
		return dg;
	}

	@Override
	public Account hqde(Account account) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("acid", account.getId());
		String hql = " from Tdemand t where t.taccount.id = :acid";
		Tdemand td = demandDao.find(hql, params).get(0);
		td.setAmount(td.getAmount() + account.getChangevalue());
		demandDao.save(td);

		Taccount ac = accountDao.get(Taccount.class, account.getId());
		ac.setAmount(ac.getAmount()+account.getChangevalue());
		accountDao.save(ac);

		Ttraderecord tr = new Ttraderecord();
		tr.setId(UUID.randomUUID().toString());
		tr.setMoney(account.getChangevalue());
		tr.setTaccount(ac);
		tr.setTradedate(new Date());
		tr.setTradeType("存款");
		// tr.setTuser();
		traderecordDao.save(tr);

		BeanUtils.copyProperties(ac, account);
		return account;
	}

	@Override
	public Account hqdr(Account account) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("acid", account.getId());
		String hql = " from Tdemand t where t.taccount.id = :acid";
		Tdemand td = demandDao.find(hql, params).get(0);
		System.out.println("1333333333333333");
		DecimalFormat df = new DecimalFormat();
		String style = "0.00";// 定义要显示的数字的格式
		df.applyPattern(style);// 将格式应用于格式化器
		try {
			if (td.getAmount() - account.getChangevalue() == 0) {
				float benjin = td.getAmount();
				float interest = ComputeUtil.Interest(td,
						dataDao.getData("hqrate"));
				td.setTamount(0);
				System.out.println(interest);
				account.setMsg("全部取款成功,共" + df.format((benjin + interest))
						+ " (本金" + df.format(benjin) + ", 利息"
						+ df.format(interest) + ")");
			} else {
				float benjin = account.getChangevalue();
				account.setMsg("部分取款成功,共" + df.format((benjin)));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		td.setAmount(td.getAmount() - account.getChangevalue());
		demandDao.save(td);

		Taccount ac = accountDao.get(Taccount.class, account.getId());
		ac.setAmount(ac.getAmount()-account.getChangevalue());
		accountDao.save(ac);

		Ttraderecord tr = new Ttraderecord();
		tr.setId(UUID.randomUUID().toString());
		tr.setMoney(account.getChangevalue());
		tr.setTaccount(ac);
		tr.setTradedate(new Date());
		tr.setTradeType("取款");
		// tr.getTuser();
		traderecordDao.save(tr);

		BeanUtils.copyProperties(ac, account);
		return account;
	}

	@Override
	public Account hqtr(Account account) {
		try {
			
		
		Map<String, Object> params2 = new HashMap<String, Object>();
		params2.put("acname", account.getToacname());
		params2.put("uname", account.getUname());
		String hql2 = " from Tdemand t where t.taccount.name = :acname and t.taccount.tuser.name=:uname";
		List<Tdemand> tdl = demandDao.find(hql2, params2);
		if(tdl.size() == 0){
			account.setMsg("信息输入错误,找不到对应账户!");
			return account;
		}
		Tdemand td2 = tdl.get(0);
		
		Taccount ac = accountDao.get(Taccount.class, account.getId());
		Taccount ac2 = td2.getTaccount();
		if(ac2.getCurrency()!=ac.getCurrency()){
			account.setMsg("对方币种与本账户不同,无法进行操作");
			return account;
		}
		
		td2.setAmount(td2.getAmount() + account.getChangevalue());
		ac2.setAmount(ac2.getAmount() + account.getChangevalue());
		
		demandDao.save(td2);
		accountDao.save(ac2);
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("acid", account.getId());
		String hql = " from Tdemand t where t.taccount.id = :acid";
		Tdemand td = demandDao.find(hql, params).get(0);
		
		DecimalFormat df = new DecimalFormat();
		String style = "0.00";// 定义要显示的数字的格式
		df.applyPattern(style);// 将格式应用于格式化器

		account.setMsg("转账成功,共" + df.format(account.getChangevalue()));

		td.setAmount(td.getAmount() - account.getChangevalue());
		demandDao.save(td);
		



		ac.setAmount(ac.getAmount()-account.getChangevalue());
		accountDao.save(ac);

		Ttraderecord tr = new Ttraderecord();
		tr.setId(UUID.randomUUID().toString());
		tr.setMoney(account.getChangevalue());
		tr.setTaccount(ac);
		tr.setTradedate(new Date());
		tr.setTradeType("转出");
		// tr.getTuser();
		traderecordDao.save(tr);
		
		Ttraderecord tr2 = new Ttraderecord();
		tr2.setId(UUID.randomUUID().toString());
		tr2.setMoney(account.getChangevalue());
		tr2.setTaccount(ac2);
		tr2.setTradedate(new Date());
		tr2.setTradeType("转入");
		// tr.getTuser();
		traderecordDao.save(tr2);

		BeanUtils.copyProperties(ac, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return account;
	}

	@Override
	public Account loadAmount(Account account) {
		Taccount ac = accountDao.get(Taccount.class, account.getId());
		account.setAmount(ac.getAmount());
		return account;
	}

	@Override
	public Account dqde(Account account) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("acid", account.getId());

		try {
			Tfixed td = new Tfixed(UUID.randomUUID().toString());
			td.setAmount(account.getChangevalue());
			td.setRate(dataDao.getData("dqrate" + account.getStype()));
			td.setStime(new Date());
			td.setStype(account.getStype());

			Taccount ac = accountDao.get(Taccount.class, account.getId());
			td.setTaccount(ac);
			fixedDao.save(td);

			ac.setAmount(ac.getAmount()+account.getChangevalue());
			accountDao.save(ac);

			Ttraderecord tr = new Ttraderecord();
			tr.setId(UUID.randomUUID().toString());
			tr.setMoney(account.getChangevalue());
			tr.setTaccount(ac);
			tr.setTradedate(new Date());
			tr.setTradeType("存款");
			// tr.setTuser();
			traderecordDao.save(tr);

			BeanUtils.copyProperties(ac, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return account;
	}

	@Override
	public Account dqdr(Account account) {
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("fid", account.getFid());

			String hql = " from Tfixed t where t.id = :fid";
			Tfixed td = fixedDao.find(hql, params).get(0);

			DecimalFormat df = new DecimalFormat();
			String style = "0.00";// 定义要显示的数字的格式
			df.applyPattern(style);// 将格式应用于格式化器
			if (td.getAmount() - account.getChangevalue() == 0) {
				float benjin = td.getAmount();
				float interest = ComputeUtil.Interest(td, td.getAmount(),
						dataDao.getData("hqrate"));
				account.setMsg("全部取款成功,共" + df.format((benjin + interest))
						+ " (本金" + df.format(benjin) + ", 利息"
						+ df.format(interest) + ")");
				fixedDao.delete(td);
			} else {
				float benjin = account.getChangevalue();
				float interest = ComputeUtil.Interest(td,
						account.getChangevalue(), dataDao.getData("hqrate"));
				account.setMsg("部分取款成功,共" + df.format((benjin + interest))
						+ " (本金" + df.format(benjin) + ", 利息"
						+ df.format(interest) + ")");
				td.setAmount(td.getAmount() - account.getChangevalue());
				fixedDao.save(td);
			}

			Taccount ac = accountDao.get(Taccount.class, account.getId());
			ac.setAmount(ac.getAmount()-account.getChangevalue());
			accountDao.save(ac);

			Ttraderecord tr = new Ttraderecord();
			tr.setId(UUID.randomUUID().toString());
			tr.setMoney(account.getChangevalue());
			tr.setTaccount(ac);
			tr.setTradedate(new Date());
			tr.setTradeType("取款");
			// tr.getTuser();
			traderecordDao.save(tr);

			BeanUtils.copyProperties(ac, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return account;
	}

	@Override
	public Account dhde(Account account) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("acid", account.getId());

		try {
			Tfixed td = new Tfixed(UUID.randomUUID().toString());
			td.setAmount(account.getChangevalue());
			td.setStime(new Date());

			Taccount ac = accountDao.get(Taccount.class, account.getId());
			td.setTaccount(ac);
			fixedDao.save(td);

			ac.setAmount(ac.getAmount()+account.getChangevalue());
			accountDao.save(ac);

			Ttraderecord tr = new Ttraderecord();
			tr.setId(UUID.randomUUID().toString());
			tr.setMoney(account.getChangevalue());
			tr.setTaccount(ac);
			tr.setTradedate(new Date());
			tr.setTradeType("存款");
			// tr.setTuser();
			traderecordDao.save(tr);

			BeanUtils.copyProperties(ac, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return account;
	}

	@Override
	public Account dhdr(Account account) {
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("fid", account.getFid());

			String hql = " from Tfixed t where t.id = :fid";
			Tfixed td = fixedDao.find(hql, params).get(0);

			DecimalFormat df = new DecimalFormat();
			String style = "0.00";// 定义要显示的数字的格式
			df.applyPattern(style);// 将格式应用于格式化器
			float benjin = td.getAmount();
			float interest = 0;
			if(DateUtil.GetDiffDays(td.getStime(), new Date()) < 365){
				interest = ComputeUtil.Interest(td, td.getAmount(),
						dataDao.getData("hqrate"));
			}else{
				interest = ComputeUtil.Interest(td, td.getAmount(),
						dataDao.getData("dqrate1")*0.6f);
			}
			
			
			account.setMsg("全部取款成功,共" + df.format(benjin + interest) + " (本金"
					+ df.format(benjin) + ", 利息" + df.format(interest) + ")");
			fixedDao.delete(td);

			Taccount ac = accountDao.get(Taccount.class, account.getId());
			ac.setAmount(ac.getAmount()-account.getChangevalue());
			accountDao.save(ac);

			Ttraderecord tr = new Ttraderecord();
			tr.setId(UUID.randomUUID().toString());
			tr.setMoney(account.getChangevalue());
			tr.setTaccount(ac);
			tr.setTradedate(new Date());
			tr.setTradeType("取款");
			// tr.getTuser();
			traderecordDao.save(tr);

			BeanUtils.copyProperties(ac, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return account;
	}

	@Override
	public DataGrid dqdataGrid(Account account, PageHelper ph) {
		DataGrid dg = new DataGrid();
		List<Fixed> acl = new ArrayList<Fixed>();
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("acid", account.getId());
		String hql = " from Tfixed t where t.taccount.id = :acid";
		List<Tfixed> l = fixedDao.find(hql + orderHql(ph), params,
				ph.getPage(), ph.getRows());
		if (l != null && l.size() > 0) {
			for (Tfixed t : l) {
				Fixed tr = new Fixed();
				BeanUtils.copyProperties(t, tr);
				acl.add(tr);
			}
		}
		dg.setRows(acl);
		dg.setTotal(fixedDao.count("select count(*) " + hql, params));
		return dg;
	}

	@Override
	public DataGrid dhdataGrid(Account account, PageHelper ph) {
		DataGrid dg = new DataGrid();
		List<Fixed> acl = new ArrayList<Fixed>();
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("acid", account.getId());
		String hql = " from Tfixed t where t.taccount.id = :acid";
		List<Tfixed> l = fixedDao.find(hql + orderHql(ph), params,
				ph.getPage(), ph.getRows());
		if (l != null && l.size() > 0) {
			for (Tfixed t : l) {
				Fixed tr = new Fixed();
				BeanUtils.copyProperties(t, tr);
				acl.add(tr);
			}
		}
		dg.setRows(acl);
		dg.setTotal(fixedDao.count("select count(*) " + hql, params));
		return dg;
	}

}
